import { Component, Host, h, VNode, ComponentInterface, Prop, Watch, Method, forceUpdate, State } from '@stencil/core';
import { IBzCalendarWeekController } from '../core/controller/ibz-calendar-week-controller';

/**
 * 日历组件「周」视图模式
 *
 * @export
 * @class IBzWeekView
 */
@Component({
    tag: 'ibz-week-view',
    styleUrl: 'ibz-week-view.scss'
})
export class IBzWeekView implements ComponentInterface {

    /**
     * 标题区DOM实例
     *
     * @protected
     * @type {HTMLDivElement}
     * @memberof IBzWeekView
     */
    protected dayHeaderWrapperRef: HTMLDivElement;

    /**
     * 日历数据
     *
     * @type {any[]}
     * @memberof IBzWeekView
     */
    @Prop()
    public items: any[];

    /**
     * 监控日历数据变更
     *
     * @param {any[]} val
     * @param {any[]} oldVal
     * @memberof IBzWeekView
     */
    @Watch('items')
    public watchItems(): void {
        this.$c.setItems(this.items || []);
        this.changeRecalculateCount();
    }

    /**
     * 定时器标识
     *
     * @protected
     * @type {number}
     * @memberof IBzWeekView
     */
    @State()
    protected time: number;

    /**
     * 日历「周」模式控制器
     *
     * @type {IBzCalendarWeekController}
     * @memberof IBzWeekView
     */
    @Prop()
    public $c: IBzCalendarWeekController;

    /**
     * 当此值变更时，「天」重新计算items
     *
     * @protected
     * @type {number}
     * @memberof IBzWeekView
     */
    @State()
    protected recalculateCount: number = 0;

    /**
     * 组件加载之前
     *
     * @memberof IBzWeekView
     */
    public componentWillLoad(): void {
        this.$c.setWeekView(this);
        if (this.items) {
            this.$c.setItems(this.items);
        }
    }

    /**
     * 内容区滚动条滚动
     *
     * @protected
     * @param {*} e
     * @memberof IBzWeekView
     */
    protected contentScroll(e: any): void {
        this.dayHeaderWrapperRef.scrollTo({ left: e.srcElement.scrollLeft });
    }

    /**
     * 绘制「周」视图模式
     *
     * @returns {VNode}
     * @memberof IBzWeekView
     */
    public render(): VNode {
        return (
            <Host class='ibz-week-view'>
                <div class='ibz-week-view-header'>
                    <div class='header-hours'></div>
                    <div ref={ref => this.dayHeaderWrapperRef = ref} class='header-days'>
                        {this.$c.dateSplits.map((item) => {
                            return <div class='header-day-item'>
                                <div class='label'>
                                    <div class='week'>{item.week}</div>
                                    <div class='date'>{item.month}/{item.day}</div>
                                </div>
                            </div>;
                        })}
                    </div>
                </div>
                <div class='ibz-week-view-content-wrapper'>
                    <div class='time-split-scale'>
                        {this.$c.hourSplits.map((item: string, i: number) => {
                            return <div class='time-split-scale-item'>
                                {i !== 0 ? <div class='label'>{item}</div> : null}
                            </div>;
                        })}
                    </div>
                    <div class='ibz-week-view-content'>
                        <div class='time-split-lines'>
                            {this.$c.hourSplits.map(() => {
                                return <div class='time-split-line-item'></div>;
                            })}
                            <div class='side-line'></div>
                            <div class='ibz-week-day-wrapper' onScroll={e => this.contentScroll(e)}>
                                {this.$c.dateSplits.map((item, i) => {
                                    return <ibz-week-day $c={this.$c} date={item.date} index={i} recalculate={this.recalculateCount}></ibz-week-day>;
                                })}
                            </div>
                        </div>
                    </div>
                </div>
            </Host>
        );
    }

    /**
     * 重新计算子数据
     *
     * @returns {Promise<void>}
     * @memberof IBzWeekView
     */
    @Method()
    public async changeRecalculateCount(): Promise<void> {
        this.time = setTimeout(() => {
            this.recalculateCount += 1;
        }, 50);
    }

    /**
     * 强制脏检查更新
     *
     * @returns {Promise<void>}
     * @memberof IBzWeekView
     */
    @Method()
    public async tick(): Promise<void> {
        forceUpdate(this);
    }

}
